
# Copyright 2009 David Lee Miller
#
# This file is part of POSSM (Python Open Source Scanning Microscopy).
#
# POSSM is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# POSSM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License         
# along with POSSM.  If not, see <http://www.gnu.org/licenses/>.
#                                                                           
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

import re,keyword
import wx.stc as stc
import cStringIO, zlib
from client import ws,wx,time,os


subs = { 'auth' : '#addauthor',
'date' : '#adddate',
'lfoot' : '#lfoot',
'rfoot' : '#rfoot',
'addimage' : '#addimage',
'insertimage' : '#insertimage',
'inumber' : '#inumber'}


head1='''\\documentclass[letterpaper,12pt]{report}
\\usepackage{graphicx}
\\usepackage{fancyhdr}
\\usepackage{txfonts}
%% Title Page
\\title{Virtual Lab\\textit{Book}}
\\author{%(auth)s}
\\date{%(date)s}

\\usepackage{fancyhdr}
\\setlength{\\headheight}{15pt}
 
\\begin{document}
\\maketitle
\\newpage
\\pagestyle{fancyplain}
\\renewcommand{\\chaptermark}[1]{\\markboth{#1}{}}
\\lhead{\\fancyplain{}{\\thepage}}
\\chead{%(date)s}
\\rhead{\\fancyplain{}{\\textit{\\leftmark}%(auth)s}}
\\lfoot{GT - Dept of Physics}
\\cfoot{}
\\rfoot{PI: Phil First}

\end{document}
''' % subs

newday='''
\\newpage
\\chead{%(auth)s}
\\rhead{\\fancyplain{}{\\textit{\\leftmark}%(date)s}}

''' % subs

figure='''
%% Scan Number %(inumber)s
\\\\begin{figure}[htp]
\\centering
\\includegraphics[width=5in]{%(addimage)s}
\\caption{%(inumber)s}
\\end{figure}
''' % subs

articlesub={'cite' : '',
    'author' : '',
    'title' : '',
    'journal' : '',
    'volume' : '',
    'number' : '',
    'pages' : '',
    'year' : '',
    'url' : '' }

articleref='''@ARTICLE{%(cite)s,
    author = \"%(author)s\",
    title = \"%(title)s\",
    journal = \"%(journal)s\",
    year = %(year)s,
    volume = %(volume)s,
    number = %(number)s,
    pages = %(pages)s,
    url = \"%(url)s\" }

'''
booksub={'author' : '',
'title' : '',
'publisher' : '',
'year' : '' }

bookref='''
@BOOK{ %(author)s,
    author = %(author)s,
    title = %(title)s",
    publisher = %(publisher)s,
    year = %(year)s,
}
'''

bibstuff='''
\\bibliographystyle{plain}
\\bibliography{%s}
'''

class AddHeading(wx.Dialog):
	'''
	Subclasses wx.Dialog. Creates additional parameters for used in creating a header
	for the virtual labbook.
	'''
	styledic={}
	styledic[1]=head1
	def __init__(self, parent, id, title):
		wx.Dialog.__init__(self, parent, id, title, size=(215, 220))

		#panel = wx.Panel(self, -1)
		#panel2 = wx.Panel(self, -1)
		self.parent=parent
		vbox = wx.FlexGridSizer(2,1,0,0)

		headbox=wx.StaticBox(self, -1, 'Heading Type')
		vbox2=wx.BoxSizer(wx.VERTICAL)
		self.rb1=wx.RadioButton(self, -1, 'Style 1', style=wx.RB_GROUP)
		vbox2.Add(self.rb1,1,wx.ALL,2)
		self.rb2=wx.RadioButton(self, -1, 'Style 2')
		vbox2.Add(self.rb2,1,wx.ALL,2)
		self.rb3=wx.RadioButton(self, -1, 'Style 3')
		vbox2.Add(self.rb3,1,wx.ALL,2)

		hbox2=wx.FlexGridSizer(1,2,0,0)
		nametxt=wx.StaticText(self, -1, 'Name')
		self.txtbox=wx.TextCtrl(self, -1, '')
		hbox2.Add(nametxt,1,wx.TOP|wx.RIGHT,5)
		self.txtbox.SetMinSize((127,27))
		hbox2.Add(self.txtbox,1,wx.ADJUST_MINSIZE|wx.ALL,0)
		vbox2.Add(hbox2,1,wx.ALL,2)

		sizer2 = wx.StaticBoxSizer(headbox,wx.VERTICAL)
		sizer2.Add(vbox2,1,wx.ALL,5)
		#self.txtbox.SetMinSize((27,50))
		hbox = wx.BoxSizer(wx.HORIZONTAL)
		okButton = wx.Button(self, -1, 'Ok')
		closeButton = wx.Button(self, -1, 'Close')
		hbox.Add(okButton, 1)
		hbox.Add(closeButton, 1, wx.LEFT, 5)

		vbox.Add(sizer2,1,wx.ALL,5)
		vbox.Add(hbox, 1, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 10)
		
		#self.Fit()
		self.SetSizer(vbox)
		okButton.Bind(wx.EVT_BUTTON,self.OnOK)
		closeButton.Bind(wx.EVT_BUTTON,self.OnClose)
	
	def OnOK(self,event):
		'''
		Adds the given information to the parent (Editor) class and closes.
		'''
		self.parent.__setattr__('author',self.txtbox.GetValue())
		self.parent.__setattr__('style',self.styledic[1])
		self.Destroy()
	def OnClose(self,event): self.Destroy()


class AddArticle(wx.Dialog):
	'''
	Subclasses wx.Dialog. Gathers information required for making
	a citation in bibTeX.
	'''
	def __init__(self, parent, id, title,type='article'):
		wx.Dialog.__init__(self, parent, id, title, size=(235, 290))

		#panel = wx.Panel(self, -1)
		#panel2 = wx.Panel(self, -1)
		self.parent=parent
		ctrlsize=(145,27)
		vbox = wx.FlexGridSizer(2,1,0,0)
		propbox=wx.FlexGridSizer(9,2,0,0)

		citetxt=wx.StaticText(self,-1,'Cite')
		propbox.Add(citetxt,1,wx.ADJUST_MINSIZE|wx.ALL,5)
		self.cite=wx.TextCtrl(self,-1,'')
		self.cite.SetMinSize(ctrlsize)
		propbox.Add(self.cite,1,wx.ADJUST_MINSIZE|wx.ALL,0)
		authortxt=wx.StaticText(self,-1,'Author')
		propbox.Add(authortxt,1,wx.ADJUST_MINSIZE|wx.ALL,5)
		self.author=wx.TextCtrl(self,-1,'')
		self.author.SetMinSize(ctrlsize)
		propbox.Add(self.author,1,wx.ADJUST_MINSIZE|wx.ALL,0)
		titletxt=wx.StaticText(self,-1,'Title')
		propbox.Add(titletxt,1,wx.ADJUST_MINSIZE|wx.ALL,5)
		self.title=wx.TextCtrl(self,-1,'')
		self.title.SetMinSize(ctrlsize)
		propbox.Add(self.title,1,wx.ADJUST_MINSIZE|wx.ALL,0)
		journaltxt=wx.StaticText(self,-1,'Journal')
		propbox.Add(journaltxt,1,wx.ADJUST_MINSIZE|wx.ALL,5)
		self.journal=wx.TextCtrl(self,-1,'')
		self.journal.SetMinSize(ctrlsize)
		propbox.Add(self.journal,1,wx.ADJUST_MINSIZE|wx.ALL,0)
		yeartxt=wx.StaticText(self,-1,'Year')
		propbox.Add(yeartxt,1,wx.ADJUST_MINSIZE|wx.ALL,5)
		self.year=wx.TextCtrl(self,-1,'')
		self.year.SetMinSize(ctrlsize)
		propbox.Add(self.year,1,wx.ADJUST_MINSIZE|wx.ALL,0)
		volumetxt=wx.StaticText(self,-1,'Volume')
		propbox.Add(volumetxt,1,wx.ADJUST_MINSIZE|wx.ALL,5)
		self.volume=wx.TextCtrl(self,-1,'')
		self.volume.SetMinSize(ctrlsize)
		propbox.Add(self.volume,1,wx.ADJUST_MINSIZE|wx.ALL,0)
		numbertxt=wx.StaticText(self,-1,'Number')
		propbox.Add(numbertxt,1,wx.ADJUST_MINSIZE|wx.ALL,5)
		self.number=wx.TextCtrl(self,-1,'')
		self.number.SetMinSize(ctrlsize)
		propbox.Add(self.number,1,wx.ADJUST_MINSIZE|wx.ALL,0)
		pagestxt=wx.StaticText(self,-1,'Pages')
		propbox.Add(pagestxt,1,wx.ADJUST_MINSIZE|wx.ALL,5)
		self.pages=wx.TextCtrl(self,-1,'')
		self.pages.SetMinSize(ctrlsize)
		propbox.Add(self.pages,1,wx.ADJUST_MINSIZE|wx.ALL,0)
		urltxt=wx.StaticText(self,-1,'URL')
		propbox.Add(urltxt,1,wx.ADJUST_MINSIZE|wx.ALL,5)
		self.url=wx.TextCtrl(self,-1,'')
		self.url.SetMinSize(ctrlsize)
		propbox.Add(self.url,1,wx.ADJUST_MINSIZE|wx.ALL,0)



		hbox = wx.BoxSizer(wx.HORIZONTAL)
		okButton = wx.Button(self, -1, 'Ok')
		closeButton = wx.Button(self, -1, 'Close')
		hbox.Add(okButton, 1)
		hbox.Add(closeButton, 1, wx.LEFT, 5)

		vbox.Add(propbox,1,wx.ALL,5)
		vbox.Add(hbox, 1, wx.ALIGN_CENTER | wx.TOP | wx.BOTTOM, 10)
		
		#self.Fit()
		self.SetSizer(vbox)
		okButton.Bind(wx.EVT_BUTTON,self.OnOK)
		closeButton.Bind(wx.EVT_BUTTON,self.OnClose)
	
	def OnOK(self,event):
		'''
		Fills in the information to the article information substitution dictionary.
		'''
		for key in articlesub.keys(): exec "articlesub[\'%s\'] = self.%s.GetValue()"%(key,key)
		self.Destroy()

	def OnClose(self,event):
		'''
		Clears any information and closes.
		'''
		for key in articlesub.keys(): exec "articlesub[\'%s\'] = \'\'"%key
		self.Destroy()

ID_TOOLBAR = wx.NewId()
ID_VIEW = wx.NewId()
ID_COMPILE = wx.NewId()
ID_ZOOMIN = wx.NewId()
ID_ZOOMOUT = wx.NewId()
ID_NEWDAY = wx.NewId()
ID_IIMAG = wx.NewId()
ID_BIBADD = wx.NewId()
ID_ARTADD = wx.NewId()

class Editor(wx.Panel):
	'''
	Creates the virtual labbook editor on a notebook page.
	'''
	filename=''
	dirname=''
	latex2pdf=ws.LATEX2PDF
	makebibtex = ws.BIBTEX
	pdfapp=ws.PDF_VIEWER
	addauth=subs['auth']
	adddate=subs['date']
	addimage=subs['addimage']
	inumber=subs['inumber']
	author=None
	style=None
	def __init__(self,frame,parent):
		wx.Panel.__init__(self,parent)
		self.parent = parent
		self.frame = frame
		self.splitter = wx.SplitterWindow(self, -1)
		self.latexedit=TeXEditor(self.splitter,'#CC0000','% LaTeX','.tex')
		self.bibtexedit=TeXEditor(self.splitter,'#00CC00','% BibTeX','.bib')
		setsize=(ws.DEFAULT_SIZE[0]*0.95,ws.DEFAULT_SIZE[1]*0.8)
		self.splitter.SetMinSize(setsize)
		self.sizer=wx.FlexGridSizer(1,1,0,0)
		self.splitter.SplitVertically(self.bibtexedit, self.latexedit,sashPosition=400)
		self.sizer.Add(self.splitter,1,wx.GROW|wx.ALL,15)
		toolbox=wx.FlexGridSizer(2,1,0,0)
		tb=self.BuildToolbar1()
		toolbox.Add(tb,1,wx.ALL|wx.ALIGN_CENTER,5)
		toolbox.Add(self.sizer,1,wx.ALL|wx.ALIGN_CENTER,2)
		self.SetSizer(toolbox)
		self.SetAutoLayout(1)
		self.sizer.Fit(self)

	def BuildToolbar1(self):

		"""
		Creates the toolbar for the editor. Images used by the toolbar are included in the
		images directory.

		"""
		tb = wx.ToolBar(self,-1,style=wx.TB_TEXT)
		self.ToolBar = tb
		tb.SetToolBitmapSize((32,32))# this required for non-standard size buttons on MSW
		tb.AddSeparator()

		tb.AddLabelTool(wx.ID_NEW, 'New', wx.Bitmap(ws.ICONPATH+'new.png'))
		wx.EVT_TOOL(self, wx.ID_NEW, self.OnNew)

		tb.AddLabelTool(wx.ID_OPEN, 'Open', wx.Bitmap(ws.ICONPATH+'open.png'))
		wx.EVT_TOOL(self, wx.ID_OPEN, self.OnOpen)

		tb.AddLabelTool(wx.ID_SAVE, 'Save', wx.Bitmap(ws.ICONPATH+'save.png'))
		wx.EVT_TOOL(self, wx.ID_SAVE, self.OnSave)

		tb.AddLabelTool(wx.ID_SAVEAS, 'Save As', wx.Bitmap(ws.ICONPATH+'save_as.png'))
		wx.EVT_TOOL(self, wx.ID_SAVEAS, self.OnSaveAs)

		tb.AddLabelTool(wx.ID_CLEAR, 'Trash', wx.Bitmap(ws.ICONPATH+'delete.png'))
		wx.EVT_TOOL(self, wx.ID_CLEAR, self.OnClear)

		tb.AddLabelTool(wx.ID_REFRESH, 'Restore', wx.Bitmap(ws.ICONPATH+'refresh.png'))
		wx.EVT_TOOL(self, wx.ID_REFRESH, self.OnRestore)

		tb.AddSeparator()

		tb.AddLabelTool(wx.ID_UNDO, 'Undo', wx.Bitmap(ws.ICONPATH+'undo.png'))
		wx.EVT_TOOL(self, wx.ID_UNDO, self.OnUndo)

		tb.AddLabelTool(wx.ID_REDO, 'Redo', wx.Bitmap(ws.ICONPATH+'redo.png'))
		wx.EVT_TOOL(self, wx.ID_REDO, self.OnRedo)

		tb.AddLabelTool(wx.ID_CUT, 'Cut', wx.Bitmap(ws.ICONPATH+'cut.png'))
		wx.EVT_TOOL(self, wx.ID_CUT, self.OnCut)

		tb.AddLabelTool(wx.ID_COPY, 'Copy', wx.Bitmap(ws.ICONPATH+'copy.png'))
		wx.EVT_TOOL(self, wx.ID_COPY, self.OnCopy)

		tb.AddLabelTool(wx.ID_PASTE, 'Paste', wx.Bitmap(ws.ICONPATH+'paste.png'))
		wx.EVT_TOOL(self, wx.ID_PASTE, self.OnPaste)
		tb.AddSeparator()

		tb.AddLabelTool(ID_ZOOMIN, 'Zoom In', wx.Bitmap(ws.ICONPATH+'zoom_in.png'))
		wx.EVT_TOOL(self, ID_ZOOMIN, self.OnZoomIn)
		
		tb.AddLabelTool(ID_ZOOMOUT, 'Zoom Out', wx.Bitmap(ws.ICONPATH+'zoom_out.png'))
		wx.EVT_TOOL(self, ID_ZOOMOUT, self.OnZoomOut)

		tb.AddSeparator()

		tb.AddLabelTool(ID_NEWDAY, 'New Day', wx.Bitmap(ws.ICONPATH+'new_day.png'))
		wx.EVT_TOOL(self, ID_NEWDAY, self.OnDay)

		tb.AddLabelTool(ID_IIMAG, 'Image Marker', wx.Bitmap(ws.ICONPATH+'insert_image.png'))
		wx.EVT_TOOL(self, ID_IIMAG, self.OnIImag)

		tb.AddLabelTool(ID_COMPILE, 'Compile', wx.Bitmap(ws.ICONPATH+'pdflatex.png'))
		wx.EVT_TOOL(self, ID_COMPILE, self.OnCompile)

		tb.AddLabelTool(ID_VIEW, 'View PDF', wx.Bitmap(ws.ICONPATH+'viewpdf.png'))
		wx.EVT_TOOL(self, ID_VIEW, self.OnView)

		tb.AddSeparator()

		tb.AddLabelTool(ID_ARTADD, 'Add Article', wx.Bitmap(ws.ICONPATH+'insert_text.png'))
		wx.EVT_TOOL(self, ID_ARTADD, self.OnArtAdd)

		tb.AddLabelTool(ID_BIBADD, 'Add BibTeX', wx.Bitmap(ws.ICONPATH+'bibtex_add.png'))
		wx.EVT_TOOL(self, ID_BIBADD, self.OnBibAdd)

		tb.AddSeparator()

		tb.Realize()

		return tb

	def OnBibAdd(self,event):
		'''
		Adds the bibliography latex information to the bottom of the document.
		'''
		success = self.latexedit.FindText(0,self.latexedit.GetTextLength(),'\\end{document}')
		if success > 0: self.latexedit.InsertText(success,bibstuff%self.GetRootName(self.filename))
			

	def OnArtAdd(self,event):
		'''
		Creates a modal from the AddArticle class. Inserts the information requested by the modal
		into the bibliography.
		'''
		dlg=AddArticle(self,-1,'',type='article')
		dlg.ShowModal()
		if not articlesub['cite']=='':
			self.bibtexedit.InsertText(0,articleref % articlesub)
			for key in articlesub.keys(): exec "articlesub[\'%s\'] = \'\'"%key

	def OnZoomIn(self,event):
		'''
		Zooms the text to a larger size.
		'''
		self.latexedit.ZoomIn()
		self.bibtexedit.ZoomIn()

	def OnZoomOut(self,event):
		'''
		Zooms the text to a smaller size.
		'''
		self.latexedit.ZoomOut()
		self.bibtexedit.ZoomOut()

	def OnUndo(self,event):
		'''
		A standard Undo call for text editing.
		'''
		if self.latexedit.GetSTCFocus(): self.latexedit.Undo()
		elif self.bibtexedit.GetSTCFocus(): self.bibtexedit.Undo()
		else: pass

	def OnRedo(self,event):
		'''
		A standard Redo call for text editing.
		'''
		if self.latexedit.GetSTCFocus(): self.latexedit.Redo()
		elif self.bibtexedit.GetSTCFocus(): self.bibtexedit.Redo()
		else: pass

	def OnCut(self,event):
		'''
		A standard cut for text editing.
		'''
		if self.latexedit.GetSTCFocus(): self.latexedit.Cut()
		elif self.bibtexedit.GetSTCFocus(): self.bibtexedit.Cut()
		else: pass

	def OnCopy(self,event):
		'''
		A standard copy for text editing.
		'''
		if self.latexedit.GetSTCFocus(): self.latexedit.Copy()
		elif self.bibtexedit.GetSTCFocus(): self.bibtexedit.Copy()
		else: pass

	def OnPaste(self,event):
		'''
		A standard paste for text editing.
		'''
		if self.latexedit.GetSTCFocus(): self.latexedit.Paste()
		elif self.bibtexedit.GetSTCFocus(): self.bibtexedit.Paste()
		else: pass

	def OnNew(self,event):
		'''
		Start a new labbook.
		'''
		dlg = AddHeading(self, -1, 'LaTeX Header')
		dlg.ShowModal()
		if self.style != None:
			self.OnClear(None)
			namesub=re.compile(self.addauth)
			header=namesub.sub(self.author,self.style)
			date=time.strftime("%m/%d/%Y")
			namesub=re.compile(self.adddate)
			header=namesub.sub(date,header)
			self.latexedit.SetText(header)
	
	def TeXName2Bib(self,filename):
		''' Convert the extension to bibtex. '''
		return filename.split('.')[0]+'.bib'
	
	def GetRootName(self,filename):
		''' Strips the extension and returns the name. '''
		return filename.split('.')[0]

	def GetExtension(self,filename):
		''' Strip the root name and return the extension. '''
		res=filename.split('.')
		if len(res)>1: return filename.split('.')[1]
		else: return ''

	def OnOpen(self, event): # Open a file
		''' Open a file '''
		dlg = wx.FileDialog(self, "Choose a file", ws.LABBOOKPATH, "", "*.tex", wx.OPEN)
		if dlg.ShowModal() == wx.ID_OK:
			# Open the LaTeX File
			self.filename = dlg.GetFilename()
			self.dirname = dlg.GetDirectory()
			f = open(os.path.join(self.dirname,self.filename),'r')
			self.latexedit.SetText(f.read())
			f.close()
			self.FindAuthor()
			# Open the BibTeX File
			f = open(os.path.join(self.dirname,self.TeXName2Bib(self.filename)),'r')
			self.bibtexedit.SetText(f.read())
			f.close()
		dlg.Destroy()
	
	def OnSave(self,event):
		if self.filename=='':
			self.OnSaveAs(None)
		else:
			# Save the LaTeX File
			pathname=os.path.join(self.dirname,self.filename)
			backupName = pathname + '.bak'
			if os.path.exists(backupName):
				os.remove(backupName)
			if os.path.exists(pathname):
				os.rename(pathname, backupName)
			self.latexedit.SaveFile(pathname)
			# Save the BibTeX File
			pathname=os.path.join(self.dirname,self.TeXName2Bib(self.filename))
			backupName = pathname + '.bak'
			if os.path.exists(backupName):
				os.remove(backupName)
			if os.path.exists(pathname):
				os.rename(pathname, backupName)
			self.bibtexedit.SaveFile(pathname)

	def OnSaveAs(self,event):
		dlg = wx.FileDialog(self, "Save As", ws.LABBOOKPATH, "", "*.tex", wx.SAVE)
		if dlg.ShowModal() == wx.ID_OK:
			# Save the LaTeX file and backup
			self.filename = dlg.GetFilename()
			self.dirname = dlg.GetDirectory()
			if not self.GetExtension(self.filename) == 'tex': self.filename = self.GetRootName(self.filename)+'.tex'
			pathname=os.path.join(self.dirname,self.filename)
			backupName = pathname + '.bak'
			if os.path.exists(backupName):
				os.remove(backupName)
			if os.path.exists(pathname):
				os.rename(pathname, backupName)
			self.latexedit.SaveFile(pathname)
			# Save the BibTeX file and backup
			pathname=os.path.join(self.dirname,self.TeXName2Bib(self.filename))
			backupName = pathname + '.bak'
			if os.path.exists(backupName):
				os.remove(backupName)
			if os.path.exists(pathname):
				os.rename(pathname, backupName)
			self.bibtexedit.SaveFile(pathname)

	def OnClear(self,event):
		dlg = wx.MessageDialog(self, 'Clear All Text?', 'Question', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
		if dlg.ShowModal() == wx.ID_YES:
			self.latexedit.ClearAll()
			self.bibtexedit.ClearAll()
	
	def OnRestore(self,event):
		dlg = wx.MessageDialog(self, 'Restore Backup?', 'Question', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
		if dlg.ShowModal() == wx.ID_YES:
			pathname1=os.path.join(self.dirname,self.filename+'.bak')
			pathname2=os.path.join(self.dirname,self.TeXName2Bib(self.filename)+'.bak')
			if os.path.exists(pathname1) and os.path.exists(pathname2):
				f = open(pathname1,'r')
				self.latexedit.SetText(f.read())
				f.close()
				f = open(pathname2,'r')
				self.bibtexedit.SetText(f.read())
				f.close()
			elif os.path.exists(pathname1):
				f = open(pathname1,'r')
				self.latexedit.SetText(f.read())
				f.close()
				dlg = wx.MessageDialog(self, 'No BibTeX Backup File Exists!', 'Error', wx.OK | wx.ICON_ERROR)
				dlg.ShowModal()
			elif os.path.exists(pathname2):
				f = open(pathname2,'r')
				self.bibtexedit.SetText(f.read())
				f.close()
				dlg = wx.MessageDialog(self, 'No LaTeX Backup File Exists!', 'Error', wx.OK | wx.ICON_ERROR)
				dlg.ShowModal()
			else:
				dlg = wx.MessageDialog(self, 'No Backup File Exists!', 'Error', wx.OK | wx.ICON_ERROR)
				dlg.ShowModal()

	def OnCompile(self,event):
		if not self.filename=='':
			pathname=os.path.join(self.dirname,self.filename)
			if os.path.exists(pathname):
				os.system(self.latex2pdf+' -output-directory '+self.dirname+' '+pathname)
				os.system("(cd "+self.dirname+";"+self.makebibtex+' '+self.GetRootName(self.filename)+")")
				os.system(self.latex2pdf+' -output-directory '+self.dirname+' '+pathname)
			else:
				dlg = wx.MessageDialog(self, pathname+' Not Found!', 'Error', wx.OK | wx.ICON_ERROR)
				dlg.ShowModal()


	def OnView(self,event):
		if not self.filename=='':
			pdfname=self.filename.split('.')[0]+'.pdf'
			pathname=os.path.join(self.dirname,pdfname)
			if os.path.exists(pathname):
				os.system(self.pdfapp+' '+pathname+' &')
			else:
				dlg = wx.MessageDialog(None, pathname+' Not Found!', 'Error', wx.OK | wx.ICON_ERROR)
				dlg.ShowModal()
	
	def FindAuthor(self):
		success = self.latexedit.FindText(0,self.latexedit.GetTextLength(),'\\author{')
		if success > 0:
			success0=self.latexedit.FindText(success,self.latexedit.GetTextLength(),'{')
			success1=self.latexedit.FindText(success,self.latexedit.GetTextLength(),'}')
			author = self.latexedit.GetTextRange(success0+1,success1)
			if not author == self.addauth: self.author=author
			else: print 'Add Author Dialog!'
	
	def OnIImag(self,event): 
		pos=self.latexedit.GetSelection()
		if pos[0] != pos[1]: self.latexedit.Clear()
		self.latexedit.InsertText(pos[0],'#imagehere')
	
	def InsertImage(self,path,scanstamp):
		'''
		Searches to find the marker where the image should be inserted, then adds the latex
		code for substitution.
		'''
		imagesub=re.compile(self.addimage)
		figure1=imagesub.sub(path,figure) # substitute path into the figure string
		inumber=re.compile(self.inumber)
		figure1=inumber.sub(scanstamp,figure1) # substitute caption into the string
		txt = self.latexedit.GetText() # add the figure to the document
		ihere = re.compile('#imagehere')
		self.latexedit.SetText(ihere.sub(figure1,txt))


	def InsDay(self,pos):
		if self.author != None: 
			namesub=re.compile(self.addauth)
			newday1=namesub.sub(self.author,newday)
		else: 
			self.FindAuthor()
			namesub=re.compile(self.addauth)
			newday1=namesub.sub(self.author,newday)
		date=time.strftime("%m/%d/%Y")
		namesub=re.compile(self.adddate)
		newday1=namesub.sub(date,newday1)
		self.latexedit.InsertText(pos,newday1)

	def OnDay(self,event): 
		success = self.latexedit.FindText(0,self.latexedit.GetTextLength(),'\\bibliography')
		if success > 0: self.InsDay(success)
		else:
			success = self.latexedit.FindText(0,self.latexedit.GetTextLength(),'\\end{document}')
			if success > 0: self.InsDay(success)


class TeXEditor(stc.StyledTextCtrl, object):
	'''
	Subclasses StyledTextCtrl to set specific properties of the
	text editor (eg. syntax highlighting, fonts...).
	'''
	if wx.Platform == '__WXMSW__':
		faces = { 'times': 'Times New Roman',
			'mono' : 'Courier New',
			'helv' : 'Arial',
			'other': 'Comic Sans MS',
			'size' : 10,
			'size2': 8,
			}
	elif wx.Platform == '__WXMAC__':
		faces = { 'times': 'Times New Roman',
			'mono' : 'Courier NOpenew',
			'helv' : 'Arial',
			'other': 'Comic Sans MS',
			'size' : 12,
			'size2': 10,
			}
	else:
		faces = { 'times': 'Times',
			'mono' : 'Courier',
			'helv' : 'Helvetica',
			'other': 'new century schoolbook',
			'size' : 12,
			'size2': 10,
			}
	def __init__(self, parent,color,name,textype):
		stc.StyledTextCtrl.__init__(self, parent, -1)
		self.SetLexer(stc.STC_LEX_LATEX)
		self.SetProperty("fold", "1")
		# No, I don't know what the next line does either!
		self.SetProperty("tab.timmy.whinge.level", "1")
		self.SetMargins(0,0)
		self.SetEdgeMode(stc.STC_EDGE_BACKGROUND)
		self.SetEdgeColumn(78)
		# Setup a margin to hold fold markers
		self.SetMarginType(2, stc.STC_MARGIN_SYMBOL)
		self.SetMarginMask(2, stc.STC_MASK_FOLDERS)
		self.SetMarginSensitive(2, True)
		self.SetMarginWidth(2, 12)
		self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPEN,    stc.STC_MARK_MINUS, "white", "black")
		self.MarkerDefine(stc.STC_MARKNUM_FOLDER,        stc.STC_MARK_PLUS,  "white", "black")
		self.MarkerDefine(stc.STC_MARKNUM_FOLDERSUB,     stc.STC_MARK_EMPTY, "white", "black")
		self.MarkerDefine(stc.STC_MARKNUM_FOLDERTAIL,    stc.STC_MARK_EMPTY, "white", "black")
		self.MarkerDefine(stc.STC_MARKNUM_FOLDEREND,     stc.STC_MARK_EMPTY, "white", "black")
		self.MarkerDefine(stc.STC_MARKNUM_FOLDEROPENMID, stc.STC_MARK_EMPTY, "white", "black")
		self.MarkerDefine(stc.STC_MARKNUM_FOLDERMIDTAIL, stc.STC_MARK_EMPTY, "white", "black")

		self.StyleSetSpec(stc.STC_STYLE_DEFAULT,     "face:%(helv)s,size:%(size)d" % TeXEditor.faces)
		self.StyleSetSpec(stc.STC_STYLE_LINENUMBER,  "back:"+color+",fore:#FF0000,face:%(helv)s,size:%(size2)d" % TeXEditor.faces)
		self.StyleSetSpec(stc.STC_STYLE_CONTROLCHAR, "face:%(other)s" % TeXEditor.faces)
		self.StyleSetSpec(stc.STC_STYLE_BRACELIGHT,  "fore:#FFFFFF,back:#0000FF,bold")
		self.StyleSetSpec(stc.STC_STYLE_BRACEBAD,    "fore:#000000,back:#FF0000,bold")
		
		# These will do for now. Eventually, the user will be able to customise them.
		#self.StyleSetSpec(stc.STC_L_DEFAULT, "fore:#000000,face:%(helv)s,size:%(size)d" % TeXEditor.faces)
		# Comments
		self.StyleSetSpec(stc.STC_L_COMMENT, "fore:#003F00,face:%(other)s,size:%(size)d" % TeXEditor.faces)
		# Commands
		self.StyleSetSpec(stc.STC_L_COMMAND, "fore:#007F7F,face:%(helv)s,bold,size:%(size)d" % TeXEditor.faces)
			# Maths
		self.StyleSetSpec(stc.STC_L_MATH, "fore:#003FFF,size:%(size)d" % TeXEditor.faces)
			# Tags (seems to be for environments etc)
			# The lexer detects \begin{foo} or \end{foo} and uses this style.
		self.StyleSetSpec(stc.STC_L_TAG, "fore:#7F007F,bold,size:%(size)d" % TeXEditor.faces)
		self.SetText(name)
		self.textype=textype